package com.yuanchu.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanchu.common.utils.DateFormatUtils;
import com.yuanchu.common.utils.PageResult;
import com.yuanchu.common.utils.R;
import com.yuanchu.store.dao.*;
import com.yuanchu.store.dto.EditStoreUserParamsDto;
import com.yuanchu.store.dto.QueryPageParams;
import com.yuanchu.store.dto.UserInfoDto;
import com.yuanchu.store.entity.*;
import com.yuanchu.store.service.YoshopStoreUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("yoshopStoreUserService")
public class YoshopStoreUserServiceImpl extends ServiceImpl<YoshopStoreUserDao, YoshopStoreUserEntity> implements YoshopStoreUserService {

    @Resource
    private YoshopStoreUserRoleDao storeUserRoleDao;
    @Resource
    private YoshopStoreMenuDao storeMenuDao;
    @Resource
    private YoshopStoreRoleMenuDao storeRoleMenuDao;
    @Resource
    private YoshopStoreRoleDao storeRoleDao;

    @Resource
    private YoshopStoreUserService storeUserService;


    @Override
    public UserInfoDto getUserInfo(Integer userId) {
        UserInfoDto userInfoDto = new UserInfoDto();
        YoshopStoreUserEntity storeUser = this.getById(userId);
        storeUser.setPassword(null);
        userInfoDto.setUserInfo(storeUser);
        // 获取用户权限
        YoshopStoreUserRoleEntity userRoleEntity = storeUserRoleDao.selectOne(new LambdaQueryWrapper<YoshopStoreUserRoleEntity>().eq(YoshopStoreUserRoleEntity::getStoreUserId, userId));
        Integer roleId = userRoleEntity.getRoleId();
        // 获取角色对应菜单权限id
        List<YoshopStoreRoleMenuEntity> storeRoleMenuList = storeRoleMenuDao.selectList(new LambdaQueryWrapper<YoshopStoreRoleMenuEntity>()
                .eq(YoshopStoreRoleMenuEntity::getRoleId, roleId)
                .eq(YoshopStoreRoleMenuEntity::getStoreId, 10001));
        List<Integer> menuIds = storeRoleMenuList.stream().map(YoshopStoreRoleMenuEntity::getMenuId).collect(Collectors.toList());
        // 获取角色对应菜单权限
        List<YoshopStoreMenuEntity> menuList = storeMenuDao.selectBatchIds(menuIds);
        List<UserInfoDto.Permission> permissionList = new ArrayList<>();
        menuList.forEach(menu -> {
            UserInfoDto.Permission permission = new UserInfoDto.Permission();
            permission.setName(menu.getName());
            permission.setPermissionId(menu.getPath());
            permission.setActionEntitySet(getActionEntitySet(menu, menuList));
            if (StringUtils.isNoneEmpty(menu.getPath())) {
                permissionList.add(permission);
            }
        });

        UserInfoDto.Roles roles = new UserInfoDto.Roles();
        roles.setIsSuper(storeUser.getIsSuper());
        roles.setPermissions(permissionList);
        userInfoDto.setRoles(roles);

        return userInfoDto;
    }

    @Override
    public PageResult<YoshopStoreUserEntity> queryStoreUserList(QueryPageParams params, Integer storeId) {
        if (params == null) {
            params = new QueryPageParams();
        }
        LambdaQueryWrapper<YoshopStoreUserEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(YoshopStoreUserEntity::getStoreId, storeId);
        Page<YoshopStoreUserEntity> page = new Page<>(params.getPage(), params.getPagesize());
        Page<YoshopStoreUserEntity> pageResult = this.page(page, lqw);
        List<YoshopStoreUserEntity> list = pageResult.getRecords();


        list.forEach(storeUser -> {
            storeUser.setPassword(null);
            storeUser.setCreateTime(DateFormatUtils.formatDatetime(storeUser.getCreateTime()));
            // 查询角色id
            List<YoshopStoreUserRoleEntity> userRole = queryUserRoleId(storeUser.getStoreUserId(), storeId);
            // 查询角色
            List<YoshopStoreRoleEntity> roles = queryStoreUserRoleList(userRole);
            storeUser.setRole(roles);
            // 角色ids
            List<Integer> roleIds = userRole.stream().map(YoshopStoreUserRoleEntity::getRoleId).collect(Collectors.toList());
            storeUser.setRoleIds(roleIds);
        });

        return PageResult.formatPageResult(list, params.getPage(), params.getPagesize(), pageResult.getTotal());
    }

    @Transactional
    @Override
    public R editStoreUser(EditStoreUserParamsDto params, Integer storeId) {
        EditStoreUserParamsDto.StoreUserForm storeUserForm = params.getForm();
        String password = storeUserForm.getPassword();
        if (StringUtils.isNotEmpty(password) && !password.equals(storeUserForm.getPasswordConfirm())) {
            return R.error("两次密码不一致");
        }
        Integer storeUserId = params.getUserId();
        YoshopStoreUserEntity storeUserEntity = this.getById(storeUserId);
        if (storeUserEntity == null) {
            return R.error("用户不存在");
        }
        if (StringUtils.isNotEmpty(password)){
            storeUserEntity.setPassword(password);
        }
        storeUserEntity.setRealName(storeUserForm.getRealName());
        storeUserEntity.setUserName(storeUserForm.getUserName());
        storeUserEntity.setSort(storeUserForm.getSort());
        storeUserEntity.setUpdateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
        boolean update = this.updateById(storeUserEntity);
        if (!update){
            return R.error("编辑失败");
        }
        // 修改用户对应角色
        if (CollectionUtils.isEmpty(storeUserForm.getRoles())){
            return R.ok("编辑成功");
        }
        storeUserService.updateUserRole(storeUserId, storeId, storeUserForm.getRoles());
        return R.ok("编辑成功");
    }

    @Transactional()
    public void updateUserRole(Integer storeUserId, Integer storeId, List<Integer> roles) {
        List<YoshopStoreUserRoleEntity> storeUserRole = storeUserRoleDao.selectList(new LambdaQueryWrapper<YoshopStoreUserRoleEntity>()
                .eq(YoshopStoreUserRoleEntity::getStoreUserId, storeUserId)
                .eq(YoshopStoreUserRoleEntity::getStoreId, storeId));
        // 根据查询是否存在记录，存在则删除数据库记录和删除对应roles
        storeUserRole.forEach(userRole -> {
            if (!roles.contains(userRole.getRoleId())){
                storeUserRoleDao.deleteById(userRole.getId());
            }else {
                // 包含，则还是原来的对应关系，不需要新增
                roles.remove(userRole.getRoleId());
            }
        });
        // 新增对应关系
        roles.forEach(roleId -> {
            YoshopStoreUserRoleEntity userRole = new YoshopStoreUserRoleEntity();
            userRole.setRoleId(roleId);
            userRole.setStoreId(storeId);
            userRole.setStoreUserId(storeUserId);
            userRole.setCreateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
            storeUserRoleDao.insert(userRole);
        });
    }

    @Override
    public R deleteStoreUser(Integer userId, Integer storeId) {
        // 软删除用户
        this.update(new UpdateWrapper<YoshopStoreUserEntity>()
                .eq("store_user_id", userId).eq("store_id", storeId).set("is_delete", 1));
        // 删除用户对应角色
        storeUserRoleDao.delete(new LambdaQueryWrapper<YoshopStoreUserRoleEntity>()
                .eq(YoshopStoreUserRoleEntity::getStoreUserId, userId)
                .eq(YoshopStoreUserRoleEntity::getStoreId, storeId));
        return R.ok("删除成功");
    }

    private List<YoshopStoreRoleEntity> queryStoreUserRoleList(List<YoshopStoreUserRoleEntity> userRoleList) {
        List<YoshopStoreRoleEntity> roles = new ArrayList<>();
        userRoleList.forEach(userRole -> {
            YoshopStoreRoleEntity storeRole = storeRoleDao.selectById(userRole.getRoleId());
            if (Objects.nonNull(storeRole)) {
                roles.add(storeRole);
            }
        });
        return roles;
    }

    private YoshopStoreUserRoleEntity getPivot(Integer roleId, List<YoshopStoreUserRoleEntity> storeUserRole) {
        for (YoshopStoreUserRoleEntity userRoleEntity : storeUserRole) {
            if (userRoleEntity.getRoleId().equals(roleId)) {
                return userRoleEntity;
            }
        }
        return null;
    }

    private List<YoshopStoreUserRoleEntity> queryUserRoleId(Integer storeUserId, Integer storeId) {
        LambdaQueryWrapper<YoshopStoreUserRoleEntity> lqw = new LambdaQueryWrapper<YoshopStoreUserRoleEntity>()
                .eq(YoshopStoreUserRoleEntity::getStoreUserId, storeUserId)
                .eq(YoshopStoreUserRoleEntity::getStoreId, storeId)
                .select(YoshopStoreUserRoleEntity::getRoleId);
        return storeUserRoleDao.selectList(lqw);
    }

    private List<UserInfoDto.ChildPer> getActionEntitySet(YoshopStoreMenuEntity menu, List<YoshopStoreMenuEntity> menuList) {
        List<UserInfoDto.ChildPer> actionEntitySet = new ArrayList<>();
        menuList.forEach(menuEntity -> {
            if (Objects.equals(menuEntity.getParentId(), menu.getMenuId())) {
                UserInfoDto.ChildPer childPer = new UserInfoDto.ChildPer();
                childPer.setAction(menuEntity.getActionMark());
                childPer.setDescribe(menuEntity.getName());
                actionEntitySet.add(childPer);
            }
        });
        return actionEntitySet;
    }

}